Advanced Usage of Python's Match-Case
Here are concise usage examples for each notable feature of Python's structural pattern matching as introduced in PEP 634 and how its different from traditional switch statement in other languages:
-
Matching Sequences
def handle_command(command): match command.split(): case [action, obj]: print(f"Action: {action}, Object: {obj}") case [action]: print(f"Action: {action}") case _: print("Unknown command") handle_command("get sword") # Output: Action: get, Object: sword -
Matching Multiple Patterns
def handle_command(command): match command.split(): case ["look"]: print("Looking around") case ["go", direction]: print(f"Going {direction}") case ["pick", obj]: print(f"Picking up {obj}") case _: print("Command not recognized") handle_command("go north") # Output: Going north -
Matching Specific Values
def handle_error(status): match status: case 404: return "Not Found" case 500: return "Server Error" case _: return "Unknown Error" print(handle_error(404)) # Output: Not Found -
Matching Multiple Values
def handle_command(command): match command.split(): case ["drop", *items]: for item in items: print(f"Dropping {item}") handle_command("drop key sword cheese") # Output: Dropping key # Dropping sword # Dropping cheese -
Adding a Wildcard
def handle_command(command): match command.split(): case ["quit"]: print("Exiting") case _: print(f"Unrecognized command: {command}") handle_command("save game") # Output: Unrecognized command: save game -
Composing Patterns
def handle_command(command): match command.split(): case ["go", "north"] | ["north"]: print("Moving north") case ["go", "south"] | ["south"]: print("Moving south") case _: print("Unknown direction") handle_command("go north") # Output: Moving north -
Capturing Matched Sub-patterns
def handle_command(command): match command.split(): case ["go", direction as d] if d in ["north", "south", "east", "west"]: print(f"Moving {d}") case _: print("Invalid direction") handle_command("go east") # Output: Moving east -
Adding Conditions to Patterns (Guards)
def handle_command(command): match command.split(): case ["go", direction] if direction in ["north", "south", "east", "west"]: print(f"Moving {direction}") case ["go", _]: print("Invalid direction") case _: print("Command not recognized") handle_command("go north") # Output: Moving north -
Matching Objects (e.g., Classes)
class Click: def __init__(self, position, button): self.position = position self.button = button def handle_event(event): match event: case Click((x, y), button="left"): print(f"Left click at ({x}, {y})") case Click((x, y), button="right"): print(f"Right click at ({x}, {y})") case _: print("Unknown event") event = Click((10, 20), "left") handle_event(event) # Output: Left click at (10, 20) -
Matching Positional Attributes
from dataclasses import dataclass @dataclass class Point: x: int y: int def handle_point(point): match point: case Point(x=0, y=0): print("Origin") case Point(x=0, y=y): print(f"On the y-axis at {y}") case Point(x=x, y=0): print(f"On the x-axis at {x}") case Point(x, y): print(f"Point at ({x}, {y})") p = Point(0, 10) handle_point(p) # Output: On the y-axis at 10 -
Matching Against Constants and Enums
from enum import Enum class Color(Enum): RED = 1 GREEN = 2 BLUE = 3 def handle_color(color): match color: case Color.RED: print("Red color") case Color.GREEN: print("Green color") case Color.BLUE: print("Blue color") case _: print("Unknown color") handle_color(Color.GREEN) # Output: Green color -
Matching Mappings
def handle_action(action): match action: case {"text": message, "color": color}: print(f"Text: {message}, Color: {color}") case {"sleep": duration}: print(f"Sleeping for {duration} seconds") case _: print("Unknown action") handle_action({"text": "Hello", "color": "blue"}) # Output: Text: Hello, Color: blue